/*
 * Copyright 2006-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.martinimix.service.payment.provider.cybersource;

import java.util.Collections;

import net.martinimix.domain.order.Order;
import net.martinimix.domain.payment.CreditCard;
import net.martinimix.service.payment.provider.cybersource.context.CyberSourceServiceRequest;
import net.martinimix.service.payment.provider.cybersource.context.OrderPaymentAuthorizationRequest;

/**
 * Provides a simple CyberSource payment services request adapter.
 * 
 * @author Scott Rossillo
 *
 */
public class SimpleCyberSourceRequestAdapter extends AbstractCyberSourceRequestAdapter implements CyberSourceRequestAdapter {
		
	/**
	 * Creates a new CyberSource request adapter.
	 */
	public SimpleCyberSourceRequestAdapter() {
		super();
		super.setAuthorizationRequestOptions(Collections.singletonMap("ccAuthService_run", "true"));
	}
	
	/**
	 * Returns a new authorization request object.
	 * 
	 * @return a new <code>OrderPaymentAuthorizationRequest</code>
	 */
	protected OrderPaymentAuthorizationRequest createRequestCommand() {
		return new OrderPaymentAuthorizationRequest();
	}
	
	/**
	 * Sets attributes common to all CybserSource service requests.
	 * 
	 * @param request the <code>OrderPaymentAuthorizationRequest</code> to set up
	 * 
	 * @param creditCard the <code>CreditCard</code> for which services will be requested
	 * 
	 * @param order the <code>Order</code> for which services will be requested
	 */
	protected final void setupCommonRequestAttributes(
			OrderPaymentAuthorizationRequest request, 
			CreditCard creditCard, 
			Order order) {
		
		String currencyCode = order.getOrderHeader().getCurrencyCode();
		
		request.setPurchaseTotalsCurrencyCode(currencyCode != null ? currencyCode : "USD");
		request.setMerchantReferenceCode(order.getOrderHeader().getExternalOrderNumber());
		
		if(isSendShippingLineItem()) {
			request.setShippingAndHandlingAmount(order.getOrderHeader().getShipAmount());
		}
		
		if(isUseOrderTotal()) {
			request.setPurchaseTotalAmount(order.getOrderHeader().getTotalPrice(), currencyCode);
		}
		
		request.setCustomer(order.getCustomer());
		request.setBillingAddress(order.getBillingAddress());
		request.setShippingAddress(order.getShippingAddress());
		request.setOrderLines(order.getOrderLines());
	}
	
	/**
	 * Prepares an authorization request.  Calls {@link #createRequestCommand()} to create
	 * the service request and then executes 
	 * {@link #setupCommonRequestAttributes(OrderPaymentAuthorizationRequest, CreditCard, Order)}
	 * before adding the given <code>creditCard</code> to the request.
	 * 
	 * @see net.martinimix.service.payment.provider.cybersource.AbstractCyberSourceRequestAdapter#prepareAuthorizationRequest(net.martinimix.domain.payment.CreditCard, net.martinimix.domain.order.Order)
	 */
	public CyberSourceServiceRequest prepareAuthorizationRequest(CreditCard creditCard, Order order) {
		
		final OrderPaymentAuthorizationRequest request = createRequestCommand();
		
		setupCommonRequestAttributes(request, creditCard, order);
		request.setCreditCard(creditCard);
		
		return request;
	}
	
}
